﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniDAQ_Ns;
using System.Timers;
using System.Configuration;

namespace Common
{
    public class PISO730 : Common.IIO
    {
        bool Opened = false;
        Timer tmr;
        private PISO730()
        {
            tmr = new Timer(20);
#if     !NO_IOCARD
            ushort wTotalBoard = 0;
            ushort wRtn = UniDAQ.Ixud_DriverInit(ref wTotalBoard);
            if (wRtn != UniDAQ.Ixud_NoErr)
            {
                throw new Exception("Driver Inital Error!!Error Code:" + wRtn.ToString());
            }
            
            tmr.Elapsed += tmr_Elapsed; 
            tmr.Start();
            Opened = true;
#endif      
        }
        public event Action StartRead;

        public void AddReadObserver(Action obj)
        {
            StartRead += obj;
        }
        public void Start()
        {
            tmr.Start();
        }
        public void Stop()
        {
            tmr.Stop();
        }
        void tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            tmr.Stop();
      
            ushort bitReadOK = ushort.Parse(ConfigurationManager.AppSettings["IOReadOK"]);
            ushort bitAllTestOK = ushort.Parse(ConfigurationManager.AppSettings["IOAllTestOK"]);
            if (ReadBit(bitAllTestOK)==false)
            {
                WriteBit(bitReadOK, false);
                if (StartRead != null)
                {
                    StartRead();
                    while (ReadBit(bitAllTestOK)==false) ;            
                }
            }
            tmr.Start();
        }
        public static readonly PISO730 Instance = new PISO730();

        public void WriteBit(ushort bitNo, bool val)
        {
#if !NO_IOCARD
            ushort wRtn = UniDAQ.Ixud_WriteDOBit(0, 0, bitNo, (ushort)(val ? 1 : 0));
            if (wRtn != UniDAQ.Ixud_NoErr)
            {
                throw new Exception("Driver Write Error!!Error Code:" + wRtn.ToString());
            } 
#endif
        }
        public void Write(uint val)
        {
            ushort wRtn = UniDAQ.Ixud_WriteDO(0, 0, val&0xff);
            if (wRtn != UniDAQ.Ixud_NoErr)
            {
                throw new Exception("Driver Write Error!!Error Code:" + wRtn.ToString());
            }
            if (val > 0xff)
            {
                wRtn = UniDAQ.Ixud_WriteDO(0, 1, val & 0xff00);
                if (wRtn != UniDAQ.Ixud_NoErr)
                {
                    throw new Exception("Driver Write Error!!Error Code:" + wRtn.ToString());
                }       
            }
        }
        public uint Read()
        {
#if !NO_IOCARD
            uint wDIVal = 0;
            uint wDIVal1 = 0;
            ushort wRtn = UniDAQ.Ixud_NoErr;
              wRtn  = UniDAQ.Ixud_ReadDI(0, 0, ref wDIVal);
            if (wRtn != UniDAQ.Ixud_NoErr)
            {
                throw new Exception("Driver Read Error!!Error Code:" + wRtn.ToString());
            }
            wRtn = UniDAQ.Ixud_ReadDI(0, 1, ref wDIVal1);
            if (wRtn != UniDAQ.Ixud_NoErr)
            {
                throw new Exception("Driver Read Error!!Error Code:" + wRtn.ToString());
            }
            wDIVal = wDIVal + (wDIVal1 <<8);
            return wDIVal; 
#else
            return 0xffffffff;
#endif
        }

        public bool ReadBit(ushort bitNo)
        {
#if !NO_IOCARD
            ushort wDIVal = 0;
            ushort port = (ushort)(bitNo / (8));
            ushort bitNO = (ushort)(bitNo % 8);
            ushort wRtn = UniDAQ.Ixud_ReadDIBit(0, port, bitNO, ref wDIVal);
            if (wRtn != UniDAQ.Ixud_NoErr)
            {
                throw new Exception("Driver Read Error!!Error Code:" + wRtn.ToString());
            }
            return wDIVal > 0 ? true : false; 
#else
            return false;
#endif
        }
        ~PISO730()
        {
            if (Opened)
                UniDAQ.Ixud_DriverClose();
        }
    }
}
